"! A collection of key-value pairs "
Collection subclass: Dictionary [
| keys values |
<category: 'Library-Collections'>
"! Info:
Return the value associated with key

Examples:
"
at: key [
^ self at: key ifAbsent: [ self noKey ]
]

"! Info:
Return the value associated with key, execute aBlock on error 

Examples:
"
at: key ifAbsent: aBlock [
| pos |
pos := keys location: key.
((pos <= keys size) and: [ key = (keys at: pos)]) ifTrue: [
	^ values at: pos
] ifFalse: [ 
	^ aBlock value 
]
]

"! Info:
Add a new value to the dictionary, associated with key

Examples:
"
at: key put: value [
| pos |
pos := keys location: key.
(pos <= keys size and: [ key = (keys at: pos)]) ifTrue: [ 
	values at: pos put: value 
] ifFalse: [ 
	keys := keys insert: key at: pos.
	values := values insert: value at: pos 
].
^ value
]

"! Info:
Execute aBlock on every key-value pair in the dictionary

Examples:
"
binaryDo: aBlock [
1 to: keys size do: [ :i | 
	aBlock value: (keys at: i) value: (values at: i) 
]
]

"! Info:
Execute aBlock on every value in the dictionary

Examples:
"
do: aBlock [
values do: aBlock
]

"! Info:
Return if this dictionary is empty

Examples:
"
isEmpty [
^ keys isEmpty
]

"! Info:
Return the keys as an array

Examples:
"
keysAsArray [
| ret |
ret := Array new: keys size.
1 to: keys size do: [ :i | 
	ret at: i put: (keys at: i)
].
^ ret
]

"! Info:
Execute aBlock on every key in the dictionary

Examples:
"
keysDo: aBlock [
1 to: keys size do: [ :i | 
	aBlock value: (keys at: i)
]
]

"! Info:
Error handler called on missing key

Examples:
"
noKey [
self error: #sysNoKey
]

"! Info:
Remove the value associated with key

Examples:
"
removeKey: key [
^ self removeKey: key ifAbsent: [ 
	self noKey 
]
]

"! Info:
Remove the value associated with key, execute aBlock on error

Examples:
"
removeKey: key ifAbsent: aBlock [
| pos |
pos := keys location: key.
(pos <= keys size and: [ key = (keys at: pos) ]) ifTrue: [
	keys := keys removeIndex: pos.
	values := values removeIndex: pos
] ifFalse: [ 
	^ aBlock value
]
]

]

"! Class methods for Dictionary "
MetaCollection subclass: MetaDictionary [
<category: 'Library-Collections'>
"! Info:
Return a new Dictionary

Examples:
"
new [
| newDict |
newDict := super new.
self in: newDict at: 1 put: (OrderedArray new: 0).
self in: newDict at: 2 put: (Array new: 0).
^ newDict
]

]

